package com.qf.emp.controller;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.qf.emp.constants.BaseConstants;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

// 根据用户的请求地址调用不同的方法
public class BaseServlet extends HttpServlet {
    // 在servlet初始化的时候给BeanUtils注册一个时间的转换器
    @Override
    public void init() throws ServletException {
        ConvertUtils.register(new Converter() {
            @Override
            public Object convert(Class type, Object value) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    return simpleDateFormat.parse(value.toString());
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }, Date.class);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        // 1.获取用户调用的action
        String action = getActionName(req.getRequestURI());
        // 2.判断action为空
        if (StringUtils.isEmpty(action)) {
            System.out.println("action不能为空");
            return;
        }
        // 3.根据actionName找到方法
        Method method = null;
        try {
            method = findActionMethod(action);
        } catch (NoSuchMethodException e) {
            System.out.println("在Servlet中没有找到【" + action + "】方法");
            return;
        }
        try {
            // 4.调用action方法
            String result = executeAction(method, req, resp);
            // 5.响应客户端
            if (!StringUtils.isEmpty(result)) {
                respClient(result, req, resp);
            }
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 根据方法的返回值响应客户端
    private void respClient(String result, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int index = result.indexOf(":");
        String type = result.substring(0, index); // 获取到跳转的方式
        String page = result.substring(index + 1); // 获取到跳转的页面
        String contextPath = req.getContextPath();
        System.out.println("contextPath:" + contextPath);
        if (BaseConstants.BASE_FORWARD.equals(type)) {
            req.getRequestDispatcher("/" + page).forward(req, resp);
        } else if (BaseConstants.BASE_REDIRECT.equals(type)) {
            resp.sendRedirect(contextPath + "/" + page);
        } else if (BaseConstants.BASE_SCRIPT.equals(type)) {
            // 以脚本形式提示用户
            resp.getWriter().write("<script>alert('" + page + "');</script>");
        } else if (BaseConstants.BASE_JSON.equals(type)) {
            resp.getWriter().write(page);
        }
    }

    // 执行方法
    private String executeAction(Method method, HttpServletRequest req, HttpServletResponse resp) throws InvocationTargetException, IllegalAccessException {
        return (String) method.invoke(this, req, resp);
    }

    // 根据acion找到具体调用的方法对象
    private Method findActionMethod(String action) throws NoSuchMethodException {
        return this.getClass().getMethod(action, HttpServletRequest.class, HttpServletResponse.class);
    }

    // 从请求地址中找到调用的action
    private String getActionName(String uri) {
        return uri.substring(uri.lastIndexOf("/") + 1);
    }

    // 根据业务层返回值来做出相应
    public String outRedirect(Boolean flag, String url) {
        if (!flag) {
            return BaseConstants.BASE_SCRIPT + ":操作失败";
        }
        return BaseConstants.BASE_REDIRECT + ":" + url;
    }

    public String outJson(Boolean flag) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200); // 默认成功，200:成功，100：失败
        if (!flag) {
            map.put("code", 100); // 覆盖
            map.put("msg", "操作失败");
        }
        String jsonString = JSON.toJSONString(map);
        System.out.println("JSON:" + jsonString);
        return BaseConstants.BASE_JSON + ":" + jsonString;
    }
}
